In this step you use the Kanzi Engine API to load the locale packs for locales in your application, and instantiate the prefabs containing the buttons and layouts for the left-to-right and right-to-left locales when the user clicks a locale button in the Kanzi application.
In this section you use the Kanzi Engine API to load the locale packs for locales in your application. You use the API to instantiate the correct IVI Grid and LocaleButton prefab with the correct layout for the selected locale.
To load the locale packs:
ja-JP zh-ZH ko-KR ar-AR he-HE
class LocalizationApplication : public ExampleApplication { // Type of the shared pointer for the custom property type defined // in the Kanzi Studio project. typedef shared_ptr<DynamicPropertyType<string> > StringDynamicPropertyTypeSharedPtr;
with
class LocalizationApplication : public ExampleApplication { // Create a set which contains the names of the right-to-left locales. set<string> m_rtlLocales;
onProjectLoaded
function first get the Locales and LocaleSelector nodes, and add the Arabic and Hebrew locales to the right-to-left locale set.onProjectLoaded
function with this:virtual void onProjectLoaded() KZ_OVERRIDE { // Get the IVI Grid node so that you can add a message filter to it. Node2DSharedPtr iviGrid = getRoot()->lookupNode<Node2D>("IVI Grid"); // Add a message filter to the IVI Grid node to find out when user clicks any of the locale buttons in the LocaleSelector node. iviGrid->addMessageFilter(ButtonConcept::ClickedMessage, bind(&LocalizationApplication::onLocaleButtonClicked, this, placeholders::_1)); // Add the right-to-left locales to the set. You use this set to identify which locales are right-to-left and use the the correct IVI Grid layout // for the selected locale. m_rtlLocales.insert("ar-AR"); m_rtlLocales.insert("he-HE"); }
onProjectLoaded
function load the localized resources from the locale packs:// Set the name of the directory where you stored the locale packs. const string localePacksDirectory = "Locale_packs"; // Read the binaries.cfg file which contains the list of locale packs kzb files. string configFileName = localePacksDirectory + "/binaries.cfg"; ifstream binariesConfigFileStream(configFileName.c_str()); string localeId; // Load the localized resources stored in the each locale pack kzb file stored in the binaries.cfg file. while (getline(binariesConfigFileStream, localeId)) { // Remove whitespace. trim(localeId); // Create the path for the kzb file. string localizationKzbFilePath = "./" + localePacksDirectory + "/" + localeId + ".kzb"; // Add the kzb file to the Kanzi resource manager. ResourceManager* resourceManager = getResourceManager(); resourceManager->addKzbFile(localizationKzbFilePath); // Get the locale dictionary. string dictionaryUrl = "kzb://localization/Locales/" + localeId; ResourceDictionarySharedPtr localeDictionary = getResourceManager()->acquireResource<ResourceDictionary>(dictionaryUrl); // From the LocaleDisplayName resource ID in the localization table of the locale get the name of the locale that you want to show in the UI. TextResourceSharedPtr localeDisplayName = localeDictionary->acquire<TextResource>(ResourceID("LocaleDisplayName")); // Get the LocaleSelector Stack Layout 2D node which positions the LocaleButton Toggle Button 2D nodes. StackLayout2DSharedPtr localeSelector = getRoot()->lookupNode<StackLayout2D>("./IVI Grid/IVI Grid LeftToRight/Locales/LocaleSelector"); // Check whether the locale is in the rtlLocales set. if (m_rtlLocales.count(localeId) > 0) { // Get the LocaleButton RightToLeft prefab and set up the button before you add it to the LocaleSelector node. Node2DSharedPtr localeButton = createLocaleButton("kzb://localization/Prefabs/LocaleButton RightToLeft", localeDictionary, localeDisplayName, localeId); // Add the LocaleButton node to the LocaleSelector node. localeSelector->addChild(localeButton); } else { // Get the LocaleButton LeftToRight prefab and set up the button before you add it to the LocaleSelector node. Node2DSharedPtr localeButton = createLocaleButton("kzb://localization/Prefabs/LocaleButton LeftToRight", localeDictionary, localeDisplayName, localeId); // Add the LocaleButton node to the LocaleSelector node. localeSelector->addChild(localeButton); } }
createLocaleButton
function, which returns either the left-to-right or right-to-left LocaleButton prefab, depending on whether the application loads a left-to-right or right-to-left locale. After the onProjectLoaded
function add:Node2DSharedPtr createLocaleButton(string url, ResourceDictionarySharedPtr localeDictionary, TextResourceSharedPtr localeDisplayName, string localeId) { // Get and instantiate the LocaleButton RightToLeft prefab used for the buttons that set right-to-left locales. // When you use the full kzb resource URL, start the path with kzb:// followed by the project name and the location of the resource. PrefabTemplateSharedPtr localeButtonPrefab = getResourceManager()->acquireResource<PrefabTemplate>(url); Node2DSharedPtr localeButton = localeButtonPrefab->instantiate<Node2D>("LocaleButton_" + localeId); // Get the custom property type for setting the name of the locale in the LocaleButton node. This custom property type is defined in the Kanzi Studio project. DynamicPropertyType<string> localeNameProperty("Localization.LocaleName"); // Get the custom property type for setting the locale in the application. This custom property type is defined in the Kanzi Studio project. DynamicPropertyType<string> localeIdProperty("Localization.LocaleID"); // Use the LocaleName property to show the name of the locale in the UI. localeButton->setProperty(localeNameProperty, localeDisplayName->getText()); // Set the LocaleID property. You get the value of this property when the user clicks a LocaleButton and use it to change the application to that locale. localeButton->setProperty(localeIdProperty, localeId); // Add the Index in Group property so that the Locales Toggle Button Group 2D node automatically sets the index of the toggle button. localeButton->setProperty(ButtonConcept::IndexInGroupProperty, -1); // Set the style of the Text Block 2D node in the LocaleButton so that it sets the correct font for the LocaleDisplayName of the locale. // Use this approach only to apply a style from the locale pack without changing the locale in the application. StyleSharedPtr style = localeDictionary->acquire<Style>(ResourceID("LocaleStyle")); localeButton->setStyle(style); return localeButton; }
createLocaleButton
function implement the onLocaleButtonClicked
event handler for the button click message from the LocaleButton nodes. When the user clicks a LocaleButton button, this event handler removes the existing layout, instantiates and adds the correct IVI Grid node layout, and sets the locale of the application.void onLocaleButtonClicked(ButtonConcept::ClickedMessageArguments& messageArguments) { // Get the custom property type for setting the locale in the application. This custom property type is defined in the Kanzi Studio project. DynamicPropertyType<string> localeIdProperty("Localization.LocaleID"); // Get the value of the LocaleID property from the button the user clicked. string localeId = messageArguments.getSource()->getProperty(localeIdProperty); // Check whether the selected locale is right-to-left or left-to-right. bool rtl = m_rtlLocales.count(localeId) > 0; // Set the path variable to the Locales Toggle Button Group 2D node in the IVI Grid layout for the selected locale. string pathToNewParent = rtl ? "IVI Grid/IVI Grid RightToLeft/Locales" : "IVI Grid/IVI Grid LeftToRight/Locales"; // Store the existing Stack Layout 2D node with the LocaleButton Toggle Button 2D nodes. StackLayout2DSharedPtr localeSelector = messageArguments.getSource()->lookupNode<StackLayout2D>(".."); // Remove the existing locale selector node from the tree. Node2DSharedPtr oldLocaleSelectorParent = localeSelector->lookupNode<Node2D>(".."); oldLocaleSelectorParent->removeChild(*localeSelector); // Set the locale of the application to the locale whose button the user selected. getScreen()->setLocale(localeId); // Get the Locales Toggle Button Group 2D node and add the LocaleSelector Stack Layout 2D node to it. ToggleButtonGroup2DSharedPtr toggleButtonGroup = getRoot()->lookupNode<ToggleButtonGroup2D>(pathToNewParent); toggleButtonGroup->addChild(localeSelector); }
In this tutorial you learned how to prepare an already localized Kanzi application for right-to-left locales and how to use the Kanzi Engine API to instantiate the prefabs which set the layout for the left-to-right and right-to-left locales. Now you can:
To find out more about how to localize your Kanzi applications, see Localization.
To learn more about kzb files, see Using kzb files.
To learn about how Kanzi handles resources, see Resource management.
To learn more about how to use resource dictionaries, see Resources.
To learn more about using fonts in your application, see Importing fonts.